
Classes consist of a name, a list of properties, and their [types](class).
In the context of LLMs, classes describe the type of the variables you can inject into prompts and extract out from the response.

<Warning>
  Note properties have no `:`
</Warning>

<CodeBlocks>
```baml Baml
class Foo {
  property1 string
  property2 int?
  property3 Bar[]
  property4 MyEnum
}
```

```python Python Equivalent
from pydantic import BaseModel
from path.to.bar import Bar
from path.to.my_enum import MyEnum

class Foo(BaseModel):
  property1: str
  property2: Optional[int]= None
  property3: List[Bar]
  property4: MyEnum
```

```typescript Typescript Equivalent
import z from "zod";
import { BarZod } from "./path/to/bar";
import { MyEnumZod } from "./path/to/my_enum";

const FooZod = z.object({
  property1: z.string(),
  property2: z.number().int().nullable().optional(),
  property3: z.array(BarZod),
  property4: MyEnumZod,
});

type Foo = z.infer<typeof FooZod>;
```

</CodeBlocks>

## Field Attributes

When prompt engineering, you can also alias values and add descriptions.

<ParamField
  path="@alias"
  type="string"
>
Aliasing renames the field for the llm to potentially "understand" your value better, while keeping the original name in your code, so you don't need to change your downstream code everytime.

This will also be used for parsing the output of the LLM back into the original object.
</ParamField>

<ParamField
  path="@description"
  type="string"
>
This adds some additional context to the field in the prompt.
</ParamField>


```baml BAML
class MyClass {
  property1 string @alias("name") @description("The name of the object")
  age int? @description("The age of the object")
}
```

## Class Attributes

<ParamField
  path="@@dynamic"
>
If set, will allow you to add fields to the class dynamically at runtime (in your python/ts/etc code). See [dynamic classes](/guide/baml-advanced/dynamic-runtime-types) for more information.
</ParamField>


```baml BAML
class MyClass {
  property1 string
  property2 int?

  @@dynamic // allows me to later propert3 float[] at runtime
}
```

## Syntax

Classes may have any number of properties.
Property names must follow these rules:
- Must start with a letter
- Must contain only letters, numbers, and underscores
- Must be unique within the class
- classes can be recursively defined!

The type of a property can be any [supported type](/ref/baml/types)

### Default values

- Not yet supported. For optional properties, the default value is `None` in python.

### Dynamic classes

See [Dynamic Types](/guide/baml-advanced/dynamic-runtime-types).

## Inheritance

Never supported. Like rust, we take the stance that [composition is better than inheritance](https://www.digitalocean.com/community/tutorials/composition-vs-inheritance).
